const BaseController = require('./baseController')
const fs = require('fs')
const path = require('path')
//故名思意 异步二进制 写入流
const awaitWriteStream = require('await-stream-ready').write
//管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole')
const dayjs = require('dayjs')

class BaseSingleUploadFileControl extends BaseController {
	// 上传文件的通用方法
	async singleUploadFile(category = '') {
		// 获取单个文件流
		// ctx.getFileStream({ requireFile: false }): 文件非必须

		const stream = await this.ctx.getFileStream()
		// 基础的目录
		const uploadBasePath = this.app.config.uploadDir
		// 生成文件名
		const filename = `${Date.now()}${Number.parseInt(
			Math.random() * 1000
		)}${path.extname(stream.filename).toLocaleLowerCase()}`
		// 生成文件夹
		const dirname = dayjs(Date.now()).format('YYYY/MM/DD')
		// 创建文件目录文件夹
		function mkdirFolderSync(dirname) {
			// 判断目录是否存在
			if (fs.existsSync(dirname)) {
				return true
			} else {
				// 递归判断
				if (mkdirFolderSync(path.dirname(dirname))) {
					fs.mkdirSync(dirname)
					return true
				}
			}
		}
		mkdirFolderSync(path.join(uploadBasePath, category, dirname))
		// 生成写入路径
		const target = path.join(uploadBasePath, category, dirname, filename)
		// 写入流
		const writeStream = fs.createWriteStream(target)
		try {
			//异步把文件流 写入
			await awaitWriteStream(stream.pipe(writeStream))
		} catch (err) {
			//如果出现错误，关闭管道
			await sendToWormhole(stream)
			return this.fail({ message: '文件出错了' })
		}
		return {
			url: path.join('public/uploads', category, dirname, filename),
			fields: stream.fields,
		}
	}
}
module.exports = BaseSingleUploadFileControl
